const CryptoJS = require('crypto-js');
const crypto = require('crypto');

class CryptoUtil {
    constructor() {
        this.algorithm = 'aes-256-gcm';
        this.keyLength = 32; // 256 bits
        this.ivLength = 16; // 128 bits
    }

    // 生成随机密钥
    generateKey() {
        return crypto.randomBytes(this.keyLength).toString('hex');
    }

    // 生成随机盐值
    generateSalt() {
        return crypto.randomBytes(16).toString('hex');
    }

    // 从密码和盐值派生密钥
    deriveKey(password, salt) {
        return crypto.pbkdf2Sync(password, salt, 100000, this.keyLength, 'sha256');
    }

    // AES-GCM加密
    encrypt(text, key) {
        try {
            const iv = crypto.randomBytes(this.ivLength);
            const cipher = crypto.createCipher(this.algorithm, key);

            let encrypted = cipher.update(text, 'utf8', 'hex');
            encrypted += cipher.final('hex');

            const authTag = cipher.getAuthTag();

            return {
                encrypted: encrypted,
                iv: iv.toString('hex'),
                authTag: authTag.toString('hex')
            };
        } catch (error) {
            console.error('加密失败:', error);
            throw error;
        }
    }

    // AES-GCM解密
    decrypt(encryptedData, key) {
        try {
            const { encrypted, iv, authTag } = encryptedData;

            const decipher = crypto.createDecipher(this.algorithm, key);
            decipher.setAuthTag(Buffer.from(authTag, 'hex'));

            let decrypted = decipher.update(encrypted, 'hex', 'utf8');
            decrypted += decipher.final('utf8');

            return decrypted;
        } catch (error) {
            console.error('解密失败:', error);
            throw error;
        }
    }

    // 简化版加密（兼容前端）
    simpleEncrypt(text, secretKey) {
        try {
            return CryptoJS.AES.encrypt(text, secretKey).toString();
        } catch (error) {
            console.error('简单加密失败:', error);
            throw error;
        }
    }

    // 简化版解密（兼容前端）
    simpleDecrypt(encryptedText, secretKey) {
        try {
            const bytes = CryptoJS.AES.decrypt(encryptedText, secretKey);
            return bytes.toString(CryptoJS.enc.Utf8);
        } catch (error) {
            console.error('简单解密失败:', error);
            throw error;
        }
    }

    // 加密对象
    encryptObject(obj, secretKey) {
        try {
            const jsonString = JSON.stringify(obj);
            return this.simpleEncrypt(jsonString, secretKey);
        } catch (error) {
            console.error('对象加密失败:', error);
            throw error;
        }
    }

    // 解密对象
    decryptObject(encryptedText, secretKey) {
        try {
            const decryptedString = this.simpleDecrypt(encryptedText, secretKey);
            return JSON.parse(decryptedString);
        } catch (error) {
            console.error('对象解密失败:', error);
            throw error;
        }
    }
}

module.exports = new CryptoUtil();
